#ifndef _Ape__Collections_Stack_h
#define _Ape__Collections_Stack_h

#include <Ape/Object.h>
#include <Ape/Collections/CollectionHelpers.h>

namespace Ape {
	namespace Collections {
	
		struct StackElement;
		
		class StackImpl : public Object {
			TYPE_NAME ("Ape::Collections::StackImpl")
		private:
			StackElement* m_Top;
			size_t m_Height;
		public:
			StackImpl();
			virtual ~StackImpl();
			
			virtual void _Dump (bool verbose = false) const;
		protected:
			void push (void* e);
			void* pop();
			size_t height() const;
		};
		
		template <typename E_t>
		class Stack : public StackImpl {
			TYPE_NAME ("Ape::Collections::Stack<E_t>")
		public:
			Stack()
			{}
			virtual ~Stack()
			{}
			
			void Push (const E_t& e) {
				void* elt = TypedHelper<E_t>::ToHeap (e);
				push (elt);
			}
			E_t Pop() {
				void* elt = pop();
				E_t e = TypedHelper<E_t>::ToStack (elt);
				TypedHelper<E_t>::Free (elt);
				return e;
			}
			size_t get_Height() const {
				return height();
			}
			virtual void _Dump (bool verbose = false) const {
				StackImpl::_Dump (verbose);
				DUMP_NON_V_TYPE;
			}
		};
		
	}
}

#endif // _Ape__Collections_Stack_h
